<html>
<head>
  <script type="text/javascript" src="https://unpkg.com/@cubejs-client/core@0.28.38/dist/cubejs-client-core.umd.js"></script>

  <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  <script type="text/javascript">
    const cubeToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjEwMDAwMDAwMDAsImV4cCI6NTAwMDAwMDAwMH0.OHZOpOBVKr-sCwn8sbZ5UFsqI3uCs6e4omT7P6WVMFw';
    const cubeHost = "https://heavy-lansford.gcp-us-central1.cubecloudapp.dev";

    const cubeApi = cubejs(cubeToken, { apiUrl: cubeHost + "/cubejs-api/v1" });

    google.charts.load('current', { packages: [ 'corechart', 'table', 'calendar' ]});

    google.charts.setOnLoadCallback(drawCharts);

    function drawCharts(artistFilters) {
      drawChartForArtworkArtists(artistFilters);
      drawChartForArtworkMediums(artistFilters);
      drawChartForArtworkYears(artistFilters);
      drawChartForArtworkWidthsHeights(artistFilters);
      drawChartForArtworkAcquisitions(artistFilters);
      drawChartForArtworkAcquisitionsIn1964(artistFilters);
      drawChartForArtworkAcquisitionsAge(artistFilters);
    }

    function buildDataTable(resultSet, labels, mapper) {
      const data = resultSet.tablePivot().map(mapper);

      if (data.length === 0) return

      return google.visualization.arrayToDataTable([ labels, ...data ]);
    }

    function buildQueryFilter(resultSet, chart, member) {
      const selectedRowNumbers = chart
        .getSelection()
        .map(function(x) { return x.row; });

      if (selectedRowNumbers.length === 0) return

      const values = resultSet
        .tablePivot()
        .filter(function(row, i) {
          return selectedRowNumbers.indexOf(i) !== -1
        })
        .map(function(row) {
          return row[member]
        })

      return {
        member,
        operator: "equals",
        values
      };
    }

    function drawChartForArtworkArtists(artistsFilter) {
      const query = {
        dimensions: [
          "Artworks.artist"
        ],
        measures: [
          "Artworks.count"
        ],
        filters: [
          {
            member: "Artworks.classification",
            operator: "equals",
            values: [ "Painting" ]
          }
        ]
      };
      
      if (artistsFilter) {
        query.filters.push(artistsFilter);
      }

      cubeApi
        .load(query)
        .then(resultSet => {
          const data = buildDataTable(resultSet, [ 'Artist', 'Paintings' ], function(row) {
            return [ row['Artworks.artist'], parseInt(row['Artworks.count']) ];
          });

          const options = {
            showRowNumber: true,
            page: 'enable',
            pageSize: 10,
            width: '100%'
          };

          const chart = new google.visualization.Table(document.getElementById('chart__artists'));
          chart.draw(data, options);

          google.visualization.events.addListener(chart, 'select', function() {
            const artistsFilter = buildQueryFilter(resultSet, chart, "Artworks.artist");

            drawChartForArtworkMediums(artistsFilter);
            drawChartForArtworkYears(artistsFilter);
            drawChartForArtworkWidthsHeights(artistsFilter);
            drawChartForArtworkAcquisitions(artistsFilter);
            drawChartForArtworkAcquisitionsIn1964(artistsFilter);
            drawChartForArtworkAcquisitionsAge(artistsFilter);
          });
        });
    }

    function drawChartForArtworkMediums(artistsFilter) {
      const query = {
        dimensions: [
          "Artworks.medium"
        ],
        measures: [
          "Artworks.count"
        ],
        filters: [
          {
            member: "Artworks.classification",
            operator: "equals",
            values: [ "Painting" ]
          }
        ]
      };

      if (artistsFilter) {
        query.filters.push(artistsFilter);
      }

      cubeApi
        .load(query)
        .then(resultSet => {
          const data = buildDataTable(resultSet, [ 'Medium', 'Paintings' ], function(row) {
            return [ row['Artworks.medium'], parseInt(row['Artworks.count']) ];
          });

          const options = {
            showRowNumber: true,
            page: 'enable',
            pageSize: 10,
            width: '100%'
          };

          new google.visualization
            .Table(document.getElementById('chart__mediums'))
            .draw(data, options);
        });
    }

    function drawChartForArtworkYears(artistsFilter) {
      const query = {
        dimensions: [
          "Artworks.year",
          "Artworks.yearAcquired"
        ],
        measures: [
          "Artworks.count"
        ],
        filters: [
          {
            member: "Artworks.classification",
            operator: "equals",
            values: [ "Painting" ]
          },
          {
            member: "Artworks.yearAcquired",
            operator: "set"
          },
          {
            member: "Artworks.year",
            operator: "set"
          }
        ]
      };

      if (artistsFilter) {
        query.filters.push(artistsFilter);
      }

      cubeApi
        .load(query)
        .then(resultSet => {
          const maxCount = resultSet
            .tablePivot()
            .reduce(function(max, row) {
              return max < row['Artworks.count'] ? row['Artworks.count'] : max;
            }, 0);

          const data = buildDataTable(resultSet,
            [ 'Year created', 'Year acquired', { type: 'string', role: 'style' } ],
            function(row) {
              return [
                parseInt(row['Artworks.year']),
                parseInt(row['Artworks.yearAcquired']),
                'point { opacity: ' + (row['Artworks.count'] / maxCount).toFixed(1) + '; }'
              ];
            }
          );

          const options = {
            title: 'Year created vs. Year acquired',
            hAxis: { viewWindowMode: 'maximized', title: 'Year created' },
            vAxis: { viewWindowMode: 'maximized', title: 'Year acquired' },
            pointSize: 3,
            height: 500,
            width: '100%',
            legend: 'none'
          };

          new google.visualization
            .ScatterChart(document.getElementById('chart__years'))
            .draw(data, options);
        });
    }

    function drawChartForArtworkWidthsHeights(artistsFilter) {
      const query = {
        dimensions: [
          "Artworks.widthCm",
          "Artworks.heightCm"
        ],
        measures: [
          "Artworks.count"
        ],
        filters: [
          {
            member: "Artworks.classification",
            operator: "equals",
            values: [ "Painting" ]
          },
          {
            member: "Artworks.widthCm",
            operator: "set"
          },
          {
            member: "Artworks.widthCm",
            operator: "lt",
            values: [ "1000" ]
          },
          {
            member: "Artworks.heightCm",
            operator: "set"
          },
          {
            member: "Artworks.heightCm",
            operator: "lt",
            values: [ "1000" ]
          }
        ]
      };

      if (artistsFilter) {
        query.filters.push(artistsFilter);
      }

      cubeApi
        .load(query)
        .then(resultSet => {
          const maxCount = resultSet
            .tablePivot()
            .reduce(function(max, row) {
              return max < row['Artworks.count'] ? row['Artworks.count'] : max;
            }, 0);

          const data = buildDataTable(resultSet,
            [ 'Width', 'Height', { type: 'string', role: 'style' } ],
            function(row) {
              const ratio = row['Artworks.widthCm'] / row['Artworks.heightCm']

              return [
                parseInt(row['Artworks.widthCm']),
                parseInt(row['Artworks.heightCm']),
                'point { ' +
                'color: ' + (ratio === 1 ? 'black' : ratio < 1 ? 'orange' : 'purple') + ';' +
                'opacity: ' + (row['Artworks.count'] / maxCount).toFixed(1) + ';' +
                ' }'
              ];
            }
          );

          const options = {
            title: 'Paintings, tall and wide',
            hAxis: { viewWindowMode: 'maximized', title: 'Width, cm' },
            vAxis: { viewWindowMode: 'maximized', title: 'Height, cm' },
            pointSize: 3,
            height: 500,
            width: '100%',
            legend: 'none'
          };

          new google.visualization
            .ScatterChart(document.getElementById('chart__widths_heights'))
            .draw(data, options);
        });
    }

    function drawChartForArtworkAcquisitions(artistsFilter) {
      const query = {
        dimensions: [
          "Artworks.yearAcquired",
        ],
        measures: [
          "Artworks.count"
        ],
        filters: [
          {
            member: "Artworks.yearAcquired",
            operator: "set"
          }
        ]
      };

      if (artistsFilter) {
        query.filters.push(artistsFilter);
      }
      
      cubeApi
        .load(query)
        .then(resultSet => {
          const data = buildDataTable(resultSet, [ 'Year', 'Paintings' ], function(row) {
            return [
              parseInt(row['Artworks.yearAcquired']),
              parseInt(row['Artworks.count']),
            ];
          });

          const options = {
            title: 'Acquisitions by year',
            height: 500,
            width: '100%',
            legend: 'none',
            trendlines: {
              0: {
                lineWidth: 1,
                color: 'green'
              }
            }
          };

          new google.visualization
            .ColumnChart(document.getElementById('chart__acquisitions'))
            .draw(data, options);
        });
    }

    function drawChartForArtworkAcquisitionsIn1964(artistsFilter) {
      const query = {
        dimensions: [
          "Artworks.dateAcquired",
        ],
        measures: [
          "Artworks.count"
        ],
        filters: [
          {
            member: "Artworks.yearAcquired",
            operator: "equals",
            values: [ "1964" ]
          }
        ]
      };

      if (artistsFilter) {
        query.filters.push(artistsFilter);
      }

      cubeApi
        .load(query)
        .then(resultSet => {
          const data = buildDataTable(resultSet, [ 'Date acquired', 'Count' ], function(row) {
            return [
              new Date(row['Artworks.dateAcquired']),
              parseInt(row['Artworks.count']),
            ];
          });

          if (data) {
            const options = {
              title: 'Acquisitions',
              colorAxis: {
                maxValue: 500
              },
              legend: 'none'
            };

            new google.visualization
              .Calendar(document.getElementById('chart__acquisitions_in_1964'))
              .draw(data, options);
          }
          else {
            document.getElementById('chart__acquisitions_in_1964').innerHTML = '';
          }
        });
    }

    function drawChartForArtworkAcquisitionsAge(artistsFilter) {
      const query = {
        dimensions: [
          "Artworks.yearAcquired",
        ],
        measures: [
          "Artworks.minAgeAtAcquisition",
          "Artworks.avgAgeAtAcquisition",
          "Artworks.maxAgeAtAcquisition"
        ],
        filters: [
          {
            member: "Artworks.yearAcquired",
            operator: "set"
          }
        ]
      };

      if (artistsFilter) {
        query.filters.push(artistsFilter);
      }

      cubeApi
        .load(query)
        .then(resultSet => {
          const data = buildDataTable(resultSet, [ 'Year acquired', 'Low', 'Open', 'Close', 'High' ], function(row) {
            return [
              row['Artworks.yearAcquired'],
              parseInt(row['Artworks.minAgeAtAcquisition']),
              parseInt(row['Artworks.avgAgeAtAcquisition']),
              parseInt(row['Artworks.avgAgeAtAcquisition']),
              parseInt(row['Artworks.maxAgeAtAcquisition'])
            ];
          });

          const options = {
            title: 'Acquisitions by age',
            colorAxis: {
              maxValue: 500
            },
            legend: 'none',
          };

          new google.visualization
            .CandlestickChart(document.getElementById('chart__acquisitions_age'))
            .draw(data, options);
        });
    }
  </script>

  <title>Google Charts Dashboard</title>

  <style>
    body {
      min-width: 1140px !important;
    }

    .dashboard {
      padding: 64px 5em;
      background-color: #f3f3fb;
      display: grid;
      grid-template-columns: 1fr;
      grid-row-gap: 5em;
    }

    .group {
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-column-gap: 5em;
    }
  </style>
</head>

<body>
<div class="dashboard">
  <!-- Charts within the dashboard -->
  <div class="group">
    <div id="chart__artists"></div>
    <div id="chart__mediums"></div>
  </div>
  <div class="group">
    <div id="chart__years"></div>
    <div id="chart__widths_heights"></div>
  </div>
  <div id="chart__acquisitions"></div>
  <div class="span" id="chart__acquisitions_in_1964"></div>
  <div class="span" id="chart__acquisitions_age"></div>
</div>
<script type="text/javascript" src="./wrapper.build.js""></script>
</body>
</html>